package com.quan.admin.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.quan.admin.commons.vo.SysUserVo;
import com.quan.admin.entity.SysPermission;
import com.quan.admin.entity.SysRole;
import com.quan.admin.entity.SysRolePermission;
import com.quan.admin.entity.SysUser;
import com.quan.admin.mapper.SysUserMapper;
import com.quan.admin.service.SysRolePermissionService;
import com.quan.admin.service.SysUserService;
import com.quan.commons.core.biz.support.MyBaseServiceImpl;
import com.quan.commons.core.constant.CommonsConstant;
import com.quan.commons.core.exception.BizException;
import com.quan.commons.core.properties.SystemValueProperties;
import com.quan.commons.core.utils.*;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


@Service
public class SysUserServiceImpl extends MyBaseServiceImpl<SysUserMapper, SysUser> implements SysUserService {

    @Autowired
	private SysUserMapper mapper;
    @Autowired
	private SysRolePermissionService rolePermissionService;

    @Autowired
    private SystemValueProperties properties;

    @Autowired
    private RedisUtils redisUtils;

	@Override
    public IPage<SysUser> selectMyPage(PageUtils pageUtils, SysUser entity) {
        Page<SysUser> page = new Page<SysUser>(pageUtils.getPage(), pageUtils.getLimit());

        // 排序
        super.handleSort(page, pageUtils);

        return this.mapper.selectMyPage(page, entity);
    }

    @Override
    public IPage<SysUser> selectPage(PageUtils pageUtils, SysUser entity) {
        QueryWrapper<SysUser> queryWrapper = new QueryWrapper<SysUser>(entity);

        if(StringUtils.isNotBlank(entity.getKeyword())) {
            queryWrapper.and(w -> {
                w.like("username", entity.getKeyword())
                .or().like("username", entity.getKeyword())
                .or().like("realname", entity.getKeyword())
                .or().like("mobile", entity.getKeyword())
                .or().like("email", entity.getKeyword());
            });
        }

        return super.selectPage(pageUtils, queryWrapper);
    }

    @Override
    public SysUser getUser(String username) {
	    QueryWrapper<SysUser> queryWrapper = new QueryWrapper<SysUser>();
	    queryWrapper.eq("username", username);
        return super.getOne(queryWrapper);
    }

    @Override
    public boolean hasFieldValue(String field, Object value) {
        return super.hasExist(field, value, SysUser.class);
    }

    @Override
    public boolean hasFieldValueForUpdate(Long id, String field, Object value) {
        QueryWrapper<SysUser> queryWrapper = new QueryWrapper<SysUser>();
        queryWrapper.eq(field, value).ne("id", id);
        if(super.count(queryWrapper) > 0) {
            return true;
        } else {
            return false;
        }
    }

    @Override
    public String login(SysUserVo vo) {
        final String username = vo.getUsername();
        final String password = vo.getPassword();

        if(StringUtils.isEmpty(username) || StringUtils.isEmpty(password)) {
            throw new BizException(20001, "账号和密码不能为空");
        }

        SysUser user = this.getUser(username);

        // 判断用户是否存在
        if(null == user) {
            throw new BizException(20001, "用户不存在");
        }
        // 验证密码是否正确
        if (!PasswordUtils.isPasswordValid(user.getPassword(), password, user.getSalt())) {
            throw new BizException(20001, "登录失败，账号或密码不正确！");
        }
        // 判断用户账号状态
        if (user.getStatus() == 0) {
            throw new BizException(20001, "账号已锁定，请联系管理员！");
        }

        Map<String, Object> map = new HashMap<String, Object>();
        map.put("id", user.getId());
        map.put("username", user.getUsername());

        final String token = JwtUtils.createToken(map, this.properties.getJwt().getSecret());

        // 将token保存到缓存中
        this.redisUtils.set(CommonsConstant.RedisPrefix.SSO_TOKEN + ":" + user.getId(), token, this.properties.getJwt().getTimeout());

        return token;
    }

    @Override
    public SysUser getUserInfo(String token) {
        final String userId = JwtUtils.getUserId(token, this.properties.getJwt().getSecret());
        final SysUser user = super.getById(userId);
        user.setPassword(null);
        return user;
    }

    @Override
    public List<SysRole> getUserRoles(Long userId) {
        return this.mapper.getUserRoles(userId);
    }

    @Override
    public List<SysPermission> getUserPermissions(Long userId) {
        return this.mapper.getUserPermissions(userId);
    }

    @Override
    public List<SysRolePermission> getUserPermissionsRelation(List<SysRole> roles) {
        List<Long> roleIds = new ArrayList<Long>() ;
        roles.forEach(item -> {
            roleIds.add(item.getId());
        });

        QueryWrapper<SysRolePermission> queryWrapper = new QueryWrapper<SysRolePermission>() ;
        queryWrapper.in("role_id", roleIds) ;
        return this.rolePermissionService.list(queryWrapper);
    }

    @Override
    public void updatePassword(Long id, String oldPassword, String newPassword) {
        SysUser entity = super.getById(id);

        if (null != entity && entity.getId() != null) {
            if (!PasswordUtils.isPasswordValid(entity.getPassword(), oldPassword, entity.getSalt())) {
                throw new RuntimeException("新密码与原密码不一致");
            }

            String salt = RandomUitl.uuid();
            // 密码加盐组成加密密码
            String encodePassword = PasswordUtils.encodePassword(newPassword, salt);

            SysUser newEntity = new SysUser();
            newEntity.setId(id);
            newEntity.setPassword(encodePassword);
            newEntity.setSalt(salt);

            super.updateById(newEntity);
        } else {
            throw new RuntimeException("修改密码失败");
        }

    }

    @Override
    public boolean batchResetPassword(List<Long> idList) {
        boolean flag = true;
        if(null != idList && !idList.isEmpty()) {
            for (Long id : idList) {

                SysUser entity = super.getById(id) ;
                entity.setSalt(RandomUitl.uuid()); // 加密盐
                String password = "123456"; // 生成6位随机密码
                entity.setPassword(PasswordUtils.encodePassword(password, entity.getSalt()));

                flag = super.updateById(entity);

                //if (flag) {
                //    // 发送短信或邮件告知用户账号和密码
                //    Map<String, Object> map = new HashMap<String, Object>();
                //    map.put("subject", "综合管理系统.密码重置");
                //    map.put("realname", entity.getRealname());
                //    map.put("username", entity.getUsername());
                //    map.put("password", password);
                //
                //    MailBean mailBean = new MailBean();
                //    mailBean.setTo(entity.getEmail());
                //    mailBean.setSubject(map.get("subject").toString());
                //    mailBean.setTemplateLocation("mail/account.html");
                //    mailBean.setTemplateData(map);
                //
                //    this.producerMessageSendMail.sender(mailBean);
                //}
            }
        }
        return flag;
    }

}